package com.liujit.upms.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlKeyword;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liujit.common.constants.ColumnConstant;
import com.liujit.common.constants.GlobalConstant;
import com.liujit.common.domain.params.BaseParams;
import com.liujit.common.domain.result.PageBean;
import com.liujit.common.exception.BusinessException;
import com.liujit.common.exception.DataNotFoundException;
import com.liujit.common.utils.CommonUtil;
import com.liujit.common.utils.DozerConvertor;
import com.liujit.common.utils.Pagination;
import com.liujit.upms.domain.model.SysOrg;
import com.liujit.upms.domain.model.SysRole;
import com.liujit.upms.domain.model.SysUser;
import com.liujit.upms.domain.params.SysOrgParams;
import com.liujit.upms.domain.query.SysOrgQuery;
import com.liujit.upms.domain.query.SysOrgTreeQuery;
import com.liujit.upms.domain.result.SysOrgResult;
import com.liujit.upms.mapper.SysOrgMapper;
import com.liujit.upms.service.SysOrgService;
import com.liujit.upms.service.SysRoleService;
import com.liujit.upms.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @Description 系统机构Service实现类
 * @Author liujun
 * @Date 2021-07-02 15:00:39
 */
@Service
public class SysOrgServiceImpl extends ServiceImpl<SysOrgMapper, SysOrg> implements SysOrgService {

    private SysUserService sysUserService;

    private SysRoleService sysRoleService;

    @Autowired
    public void setSysUserService(SysUserService sysUserService) {
        this.sysUserService = sysUserService;
    }

    @Autowired
    public void setSysRoleService(SysRoleService sysRoleService) {
        this.sysRoleService = sysRoleService;
    }

    @Override
    public PageBean<SysOrgResult> getPage(SysOrgQuery query) {
        // 排序
        if (StrUtil.isNotBlank(query.getSortName()) && StrUtil.isNotBlank(query.getSortOrder())) {
            query.setSortName(ColumnConstant.CREATE_TIME);
            query.setSortOrder(SqlKeyword.DESC.getSqlSegment());
        }
        Page<SysOrg> page = Pagination.page(query);
        LambdaQueryWrapper<SysOrg> wrapper = new LambdaQueryWrapper();
        if (StrUtil.isNotBlank(query.getName())) {
            wrapper.like(SysOrg::getName, query.getName());
        }
        if (query.getPid() != null) {
            wrapper.eq(SysOrg::getPid, query.getPid());
        }
        if (query.getEnabled() != null) {
            wrapper.eq(SysOrg::getEnabled, query.getEnabled());
        }
        if (query.getStartTime() != null) {
            wrapper.ge(SysOrg::getCreateTime, query.getStartTime());
        }
        if (query.getEndTime() != null) {
            wrapper.le(SysOrg::getCreateTime, query.getEndTime());
        }
        IPage<SysOrg> iPage = super.page(page, wrapper);
        return PageBean.page(iPage, SysOrgResult.class);
    }

    @Override
    public Boolean save(SysOrgParams params) {
        SysOrg entity = DozerConvertor.convertor(params, SysOrg.class);
        // 添加
        if (params.getId() == null) {
            entity.setEnabled(GlobalConstant.ENABLED_YES);
            // 查询当前父id的编号
            String maxCode = super.baseMapper.selMaxCodeByPid(entity.getPid());
            entity.setCode(CommonUtil.getCode(maxCode, params.getPcode()));
            return super.save(entity);
        } else {
            SysOrg sysOrg = super.getById(params.getId());
            if (sysOrg == null) {
                throw new DataNotFoundException();
            }
            return super.updateById(entity);
        }
    }

    @Override
    public SysOrgResult get(Long id) {
        SysOrg sysOrg = super.getById(id);
        if (sysOrg == null) {
            throw new DataNotFoundException();
        }
        return DozerConvertor.convertor(sysOrg, SysOrgResult.class);
    }

    @Override
    public SysOrgResult getDetail(Long id) {
        SysOrgResult result = this.get(id);
        // 查询父id名称
        if (result.getPid() > 0) {
            result.setPname(this.getNameById(result.getPid()));
        }
        return result;
    }

    @Override
    public Boolean del(BaseParams params) {
        SysOrg sysOrg = super.getById(params.getId());
        if (sysOrg == null) {
            throw new DataNotFoundException();
        }
        // 查询节点是否有数据
        LambdaQueryWrapper<SysOrg> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrg::getPid, sysOrg.getId());
        Integer count = super.count(wrapper);
        if (count > 0) {
            throw new BusinessException("机构下有数据，不能删除");
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(SysRole::getOrgId, sysOrg.getId());
        count = sysRoleService.count(roleWrapper);
        if (count > 0) {
            throw new BusinessException("机构下有角色，不能删除");
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysUser::getOrgId, sysOrg.getId());
        count = sysUserService.count(userWrapper);
        if (count > 0) {
            throw new BusinessException("机构下有用户，不能删除");
        }
        return super.removeById(params.getId());
    }

    @Override
    public Boolean enabled(BaseParams params) {
        SysOrg sysOrg = super.getById(params.getId());
        if (sysOrg == null) {
            throw new DataNotFoundException();
        }
        return super.updateById(new SysOrg() {{
            setId(params.getId());
            setEnabled(GlobalConstant.ENABLED_YES);
        }});
    }

    @Override
    public Boolean disabled(BaseParams params) {
        SysOrg sysOrg = super.getById(params.getId());
        if (sysOrg == null) {
            throw new DataNotFoundException();
        }
        // 查询节点是否有数据
        LambdaQueryWrapper<SysOrg> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysOrg::getPid, sysOrg.getId());
        Integer count = super.count(wrapper);
        if (count > 0) {
            throw new BusinessException("机构下有数据，不能禁用");
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysRole> roleWrapper = new LambdaQueryWrapper<>();
        roleWrapper.eq(SysRole::getOrgId, sysOrg.getId());
        count = sysRoleService.count(roleWrapper);
        if (count > 0) {
            throw new BusinessException("机构下有角色，不能禁用");
        }
        // 查询节点是否有用户
        LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(SysUser::getOrgId, sysOrg.getId());
        count = sysUserService.count(userWrapper);
        if (count > 0) {
            throw new BusinessException("机构下有用户，不能禁用");
        }
        return super.updateById(new SysOrg() {{
            setId(params.getId());
            setEnabled(GlobalConstant.ENABLED_NO);
        }});
    }

    @Override
    public List<Tree<Long>> getTree(SysOrgTreeQuery query) {
        LambdaQueryWrapper<SysOrg> wrapper = new LambdaQueryWrapper();
        wrapper.orderByAsc(SysOrg::getSeq);
        if (StrUtil.isNotBlank(query.getName())) {
            wrapper.like(SysOrg::getName, query.getName());
        }
        if (query.getEnabled() != null) {
            wrapper.eq(SysOrg::getEnabled, query.getEnabled());
        }
        List<SysOrg> list = super.list(wrapper);
        // 配置树
        TreeNodeConfig config = new TreeNodeConfig();
        config.setParentIdKey("pid");
        config.setNameKey("name");
        config.setWeightKey("seq");
        // 排序字段
        return TreeUtil.build(list, 0L, config, (object, tree) -> {
            tree.putExtra("id", object.getId());
            tree.putExtra("pid", object.getPid());
            tree.putExtra("name", object.getName());
            tree.putExtra("code", object.getCode());
        });
    }

    @Override
    public String getNameById(Long id) {
        LambdaQueryWrapper<SysOrg> wrapper = new LambdaQueryWrapper<>();
        wrapper.select(SysOrg::getName);
        wrapper.eq(SysOrg::getId, id);
        return super.getObj(wrapper, item -> Convert.toStr(item));
    }
}
